

from typing import Any, Generic, Optional, TypeVar
import typing
import json
from fastapi import BackgroundTasks, Response
from pydantic import BaseModel
from pydantic.generics import GenericModel
from fastapi.responses import JSONResponse

from app.common.enums.resp_enum import ErrTypes, RespEnum

DataT = TypeVar('DataT')

# API基础响应类
class APIBaseResp(BaseModel):
    code: str = RespEnum.success.value[0]
    #type: str = RespTypeEnum.success.value
    message: str = RespEnum.success.value[1]
    #data: Optional[Any] = None
    #error: Optional[Any] = []

# 通用API响应类
class APIResponse(GenericModel, Generic[DataT]):
    code: str = RespEnum.success.value[0]
    message: str = RespEnum.success.value[1]
    data: Optional[DataT] = None
    #error: Optional[Any] = []

class GenericJSONResponse(Response):
    media_type = "application/json"

    def __init__(
        self,
        content: typing.Any,
        status_code: int = 200,
        headers: typing.Optional[typing.Dict[str, str]] = None,
        media_type: typing.Optional[str] = None,
        background: typing.Optional[BackgroundTasks] = None,
    ) -> None:
        super().__init__(content, status_code, headers, media_type, background)

    def render(self, content: typing.Any) -> bytes:
        return json.dumps(
            content,
            ensure_ascii=False,
            allow_nan=False,
            indent=None,
            separators=(",", ":"),
        ).encode("utf-8")


class GenericResp:

    message: str | None = None
    code: str
    data: str | dict | list | None = None
    status_code: int
    error: str | None = None

    def __init__(
        self, 
        data: str | dict | list | None = None,
        code: str = '000000',
        message: str = 'success',
        status_code: int = 200,
        error: str | None = None
    ):
        self.data = data
        self.code = code
        self.message = message
        self.status_code = status_code
        self.error = error
        #super().__init__(self.get_response(), status_code)

    def __call__(self, *args: Any, **kwds: Any) -> Any:
        print('>> __call__')
        return self.get_response()
        

    def get_response(self):
        resp_body = {
            'message': self.message,
            'code': self.code
        }
        if self.data:
            resp_body['data'] = self.data
        if self.error:
            resp_body['error'] = self.error
        return JSONResponse(resp_body, status_code=self.status_code)
    
class GenericErrResp(GenericResp):
    def __init__(
        self, 
        err_type: ErrTypes = ErrTypes.unknown_error,
        code: Optional[str] = None,
        message: Optional[str] = None,
        status_code: Optional[int] = 200,
        error: str | None = None
    ):
        #super.__init__()
        self.code = code or err_type.value[0]
        self.message = message or err_type.value[1]
        self.status_code = status_code
        self.error = error